www.gusucode.com > 有监督的 CNN 网络完成对MNIST 数字的识别 > 有监督的 CNN 网络完成对MNIST 数字的识别/CNN—卷积神经网络数字识别/cutrain_cnn.m

    %为handwriten数字卷积神经网络识别:培训和仿真。
%这个程序实现卷积神经网络对MNIST handwriten数字识别,卷积神经网络,定义任意的结构和参数。
%假定MNIST数据库位于”./ MNIST”目录中。
%参考文献:
% 1、 Y. LeCun, L. Bottou, G. Orr and K. Muller: Efficient BackProp, in Orr, G.
%and Muller K. (Eds), Neural Networks: Tricks of the trade, Springer, 1998
%URL:http://yann.lecun.com/exdb/publis/index.html。
% 2、Y. LeCun, L. Bottou, Y. Bengio and P. Haffner: Gradient-Based
% Learning(梯度学习)
%用于文档识别、IEEE学报,86(11):2278 - 2324年,1998年11月
%URL:http://yann.lecun.com/exdb/publis/index.html。
% 3、 Patrice Y. Simard, Dave Steinkraus, John C. Platt: Best Practices for
%卷积神经网络应用于视觉文档分析(Convolutional Neural Networks Applied to Visual Document Analysis)
%URL:http://research.microsoft.com/apps/pubs/?id=68920。
% 感谢麦克·奥尼尔,他伟大的文章总结和概括的所有信息
%编程:
%URL:http://www.codeproject.com/KB/library/NeuralNetRecognition.aspx。

clear;
clc;
%数字加载到工作区
[I,labels,I_test,labels_test] = readMNIST(1000); 
%%
%定义结构根据[2]
%总层数

numLayers = 8; 
%二次抽样层
numSLayers = 3; 
%卷积层
numCLayers = 3; 
% 数量的完全连接层
numFLayers = 2;
%一定数量输入图像(同时加工)。需要将来的版本中,现在只有1是可能的
numInputs = 1; 
%图像的宽度
InputWidth = 32; 
%图像的高度
InputHeight = 32;
%数量的输出
numOutputs = 10; 
% 创建一个空的卷积神经网络
sinet = cnn(numLayers,numFLayers,numInputs,InputWidth,InputHeight,numOutputs);
%定义网络参数
%将实现细节层总是成对。首先必须二次抽样,最后(fulli连接之前)是卷积层。
%这就是为什么这里的第一层是虚拟的。
sinet.SLayer{1}.SRate = 1;
sinet.SLayer{1}.WS{1} = ones(size(sinet.SLayer{1}.WS{1}));
sinet.SLayer{1}.BS{1} = zeros(size(sinet.SLayer{1}.BS{1}));
sinet.SLayer{1}.TransfFunc = 'purelin';
%重量1
%偏差1
%卷积核心是5x5规模


sinet.CLayer{2}.numKernels = 6;
sinet.CLayer{2}.KernWidth = 5;
sinet.CLayer{2}.KernHeight = 5;
%重量150
%偏差6

%第三层
%二次抽样率
sinet.SLayer{3}.SRate = 2;
%Weights 6
%Biases 6

%第四层- 16内核与5 x5的大小
sinet.CLayer{4}.numKernels = 16;
sinet.CLayer{4}.KernWidth = 5;
sinet.CLayer{4}.KernHeight = 5;
%重量150
%偏差6

%第五层
%二次抽样率
sinet.SLayer{5}.SRate = 2;
%Weights 6
%Biases 6

%第六层,输出120特征图1 x1大小
sinet.CLayer{6}.numKernels = 120;
sinet.CLayer{6}.KernWidth = 5;
sinet.CLayer{6}.KernHeight = 5;
%重量 3000
%偏差 120

%第七层——完全连接,84个神经元
sinet.FLayer{7}.numNeurons = 84;


%八层——完全连接,10个输出神经元
sinet.FLayer{8}.numNeurons = 10;


%初始化网络
sinet = init(sinet);

%根据[2]概括如果有unsimmetry层连接是更好的。使用这种连接图:
sinet.CLayer{4}.ConMap = ...
[1 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1;
 1 1 0 0 0 1 1 1 0 0 1 1 1 1 0 1;
 1 1 1 0 0 0 1 1 1 0 0 1 0 1 1 1;
 0 1 1 1 0 0 1 1 1 1 0 0 1 0 1 1;
 0 0 1 1 1 0 0 1 1 1 1 0 1 1 0 1; 
 0 0 0 1 1 1 0 0 1 1 1 1 0 1 1 1; 
]';
%,但一些论文提出随机生成地图的连接。可以试一试:
%sinet.CLayer{6}.ConMap = round(rand(size(sinet.CLayer{6}.ConMap))-0.1);
sinet.SLayer{1}.WS{1} = ones(size(sinet.SLayer{1}.WS{1}));
sinet.SLayer{1}.BS{1} = zeros(size(sinet.SLayer{1}.BS{1}));
%在我impementation输出层是普通隐藏层而不是[1、2],但是我打算实现径向基输出层

%sinet.FLayer{8}.TransfFunc = 'radbas';


%%
%现在最后的准备工作是训练的代数
sinet.epochs = 3;
%Mu coefficient for stochastic Levenberg-Markvardt(随机产生系数)
sinet.mu = 0.001;
%训练系数
%sinet.teta =  [50 50 20 20 20 10 10 10 5 5 5 5 1]/100000;
sinet.teta =  0.0005;
%0 - 黑森运行估计是每个迭代计算
%1 - 黑森近似是每个cnet重新计算。Hrecomp迭代
%2 - 没有黑森计算。纯随机梯度
sinet.HcalcMode = 2;
sinet.Hrecalc = 300; %%迭代次数为黑森重算通过
sinet.HrecalcSamplesNum = 50; %黑森的样本数量重新计算

%Teta降低系数
sinet.teta_dec = 0.4;

%图像预处理。产生的图像1 0均值和标准偏差。进去的preproc_data细节
[Ip, labtrn] = preproc_data(I,1000,labels,0);
[I_testp, labtst] = preproc_data(I_test,200,labels_test,0);
%训练
sinet = cutrain(sinet,Ip,labtrn,I_testp,labtst);